package net.sevear.chaos.p2p
{
	import flash.events.Event;
	import flash.net.SharedObject;
	import flash.utils.setTimeout;
	
	import mx.collections.ArrayCollection;
	
	import net.sevear.chaos.douban.NeedUpdatedPlayList;
	import net.sevear.chaos.douban.shuo.DBShuoEvent;
	import net.sevear.chaos.douban.shuo.DBShuoTimeLine;
	import net.sevear.chaos.event.p2p.P2pOffLineEvent;
	import net.sevear.chaos.view.ChaosLogPanel;
	import net.sevear.chaos.vo.TrackInfo;
	import net.sevear.chaos.vo.UserInfo;
	
	public class DBShuoOffLineSource extends P2POffLineSource
	{
		public static const SEQ:int 		= 0;
		public static const CIRCLE:int 		= 1;
		private static const MAX_RETRY_TIME:int = 3;
		
		private var so:SharedObject;
		private var timeline:DBShuoTimeLine;
		private var curList:ArrayCollection;
		private var untilID:int;
		private var retryTime:int = 0;
		private var waitingList:Array = [];
		private var updateList:NeedUpdatedPlayList;
		private var p2pServerID:int;
		public function DBShuoOffLineSource()
		{
			super();
		}
		
		//FIXME:MAYBE USER==NULL
		override public function init(user:UserInfo):void{
			timeline = new DBShuoTimeLine(user.dbUID);
			p2pServerID = user.dbID;
			timeline.addEventListener(DBShuoEvent.TIME_LINE_UPDATED,onGetTimeLine);
			timeline.addEventListener(DBShuoEvent.TIME_LINE_UPDATED_FAILED,onTimeLineFailed);
			untilID = -1;
//			initSO();
			dispatchEvent(new P2pOffLineEvent(P2pOffLineEvent.INIT_FINISHED));
		}
		
		override public function getList(lastPlayID:int):Array{
			if(lastPlayID == -1){
				//NEWEST
				return getSliceList(-1);
			}else{
				var searchIdx:int = searchLastPlayElem(lastPlayID);
				if(searchIdx<0){
					return getSliceList(-1);
				}else{
					return getSliceList(searchIdx);
				}
			}
		}
		
		override public function requestList():void{
			ChaosLogPanel.getInstance().addTempBasicInfo("获取豆瓣说音乐推荐中...");
			timeline.loadTimeLine(untilID);
		}
		
		public function stop():void{
			timeline.stopLoad();
			if(updateList!=null && updateList.running()){
				updateList.stopUpdate();
			}
		}
		
		private function initSO():void{
			so = SharedObject.getLocal("douchaos","/");
			if(so.data["p2p"+p2pServerID+"ShuoUntilID"]!=null){
				untilID = parseInt(so.data["p2p"+p2pServerID+"ShuoUntilID"] as String);
			}else{
				so.data["p2p"+p2pServerID+"ShuoUntilID"] = untilID.toString();
				so.flush();
			}
		}
		
		//FIXME:优化一下
		private function searchLastPlayElem(lastPlayId:int):int{
			var elem:TrackInfo = searchTrackInList(lastPlayId,curList.source);
			if(elem!=null){
				return curList.getItemIndex(elem);
			}else{
				return -1;
			}
		}
		
		private function getSliceList(startIdx:int,len:int=10,circle:int = SEQ):Array{
			if(curList==null) return null;
			else{
				var newlist:Array = [];
				for(var i:int = startIdx+1;i<len+startIdx&&i<curList.length;i++){
					newlist.push(curList.getItemAt(i));
				}
				//TODO:CIRCLE
				return newlist;
			}
		}
		
		private function onGetTimeLine(e:DBShuoEvent):void{
			var rst:Array = e.data.result as Array;
			untilID = e.data.lastID as int;
			if(rst.length==0){
				dispatchEvent(new P2pOffLineEvent(P2pOffLineEvent.ALL_ITEMS_GOTTEN));
			}else{
				var newTrackList:Array = [];
				for(var i:int = 0;i<rst.length;i++){
					var shuoObj:Object;
					shuoObj = rst[i];
					if(shuoObj.type=="rec_fm"){
						
						var track:TrackInfo = new TrackInfo();
						var requrl:String = shuoObj.attachments[0].expaned_href as String;
						//TODO:DJ频道的不是单曲是节目
						if(requrl.search("cid=dj")>0){
							trace("receive dj programme, skip");
							continue;
						}else{
							var sidRst:Array = requrl.match(/[\d]*g/);
							if(sidRst!=null){
								track.sid = parseInt((sidRst[0] as String).substring(0,(sidRst[0] as String).length-1));
							}
							
							var g0Idx:int = requrl.search(/g[\d]*&cid=/);
							if(g0Idx>0){
								track.ssid = requrl.slice(
									("http://douban.fm/?start="+track.sid.toString()+"g").length,
									g0Idx);
							}
							track.subtype = TrackInfo.RECOMMEND;
							//FIXME:可能会很长。。。
							newTrackList.push(track);
						}
					}
				}
				
				if(newTrackList.length>0){
					if(curList==null || curList.length<1){
						handleTopestList(newTrackList,2);
					}else{
						waitingList = newTrackList;
						updateList = new NeedUpdatedPlayList(mergeTrackList(newTrackList));
						updateList.addEventListener(NeedUpdatedPlayList.ALL_ITEMS_LISTEN_READY,onAllReItemsUpdated);
						updateList.startUpdate();
					}
				}else{
					timeline.loadTimeLine(untilID);
				}
			}
		}
		
		
		private function handleTopestList(rawArr:Array,len:int):void{
			if(rawArr.length>0){
				waitingList = rawArr;
				var toplist:Array = [];
				for(var i:int = 0;i<rawArr.length && i<len;i++){
					toplist.push(rawArr.shift());
				}
//				toplist.reverse();
				updateList = new NeedUpdatedPlayList(mergeTrackList(toplist));
				updateList.addEventListener(NeedUpdatedPlayList.ALL_ITEMS_LISTEN_READY,onAllReItemsUpdated);
				updateList.startUpdate();
			}
		}
		
		private function mergeTrackList(rawTrackList:Array):Array{
			var trackList:Array = new Array();
			for each(var track:TrackInfo in rawTrackList){
				if(searchTrackInList(track.sid,trackList)==null){
					trackList.push(track);
				}
			}
			return trackList;
		}
		
		private function searchTrackInList(sid:int,list:Array):TrackInfo{
			if(list!=null){
				for each(var track:TrackInfo in list){
					if(sid==track.sid)
						return track;
				}
				return null;
			}else return null;
		}
		
		private function onAllReItemsUpdated(e:Event):void{
			var list:NeedUpdatedPlayList = (e.currentTarget as NeedUpdatedPlayList);
			list.removeEventListener(NeedUpdatedPlayList.ALL_ITEMS_LISTEN_READY,onAllReItemsUpdated);
			if(curList==null) curList = new ArrayCollection();
			for each(var track:TrackInfo in (e.currentTarget as ArrayCollection)){
				curList.addItem(track);
				trace("Offline Track ",track.name ," is ready ");
			}
			dispatchEvent(new P2pOffLineEvent(P2pOffLineEvent.NEW_LIST_GOTTEN));
			if(waitingList!=null && waitingList.length>0){
				updateList = new NeedUpdatedPlayList(mergeTrackList(waitingList));
				waitingList = [];
				updateList.addEventListener(NeedUpdatedPlayList.ALL_ITEMS_LISTEN_READY,onAllReItemsUpdated);
				updateList.startUpdate();
			}
		}
		
		private function onTimeLineFailed(e:DBShuoEvent):void{
			if(retryTime<MAX_RETRY_TIME){
				retryTime++;
				setTimeout(requestList,3000);
			}else{
				dispatchEvent(new P2pOffLineEvent(P2pOffLineEvent.UN_UNAVIABLE));
			}
		}
	}
}